package cn.ac.siom.query.action;

import cn.ac.siom.query.common.SiomConstants;
import cn.ac.siom.query.common.exception.UserNotPermitException;
import cn.ac.siom.query.common.exception.UserWaittingPermitException;
import cn.ac.siom.query.service.UserService;
import cn.ac.siom.query.util.SessionUtil;
import cn.ac.siom.query.vo.Permission;
import cn.ac.siom.query.vo.ReturnMsg;
import cn.ac.siom.query.vo.Role;
import cn.ac.siom.query.vo.Sys_user;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.UnauthorizedException;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import java.sql.SQLException;
import java.util.HashSet;
import java.util.Set;

@Controller
@RequestMapping("/")
public class UserController{
    public static final Logger LOGGER = LoggerFactory.getLogger(UserController.class);

    @Resource
    private UserService getUserService;


    /**
     * 登录
     */
    @RequestMapping(value = "dologin", method = RequestMethod.POST)
    @ResponseBody
    public ReturnMsg doLogin(Sys_user user) {
        ReturnMsg msg = new ReturnMsg();
        String userName = user.getU_idcard();
        String password = user.getU_pwd();
        UsernamePasswordToken token = new UsernamePasswordToken(userName, password);
        token.setRememberMe(true);
        Subject subject = SecurityUtils.getSubject();
        try {
            subject.login(token);
            subject.isAuthenticated();
            subject.isPermitted("edit");
            if (subject.isAuthenticated()) {
                // 根据用户名查询当前用户权限
                Sys_user user2 = null;
                try {
                    user2 = getUserService.findPermissions(userName);
                } catch (SQLException e) {
                    e.printStackTrace();
                }
                Set<String> permissionNames = new HashSet<String>();
                if(user2.getRoleList() != null) {
                    for (Role role : user2.getRoleList()) {
                        for (Permission permission : role.getPermissionList()) {
                            permissionNames.add(permission.getPname());
                        }
                    }
                }else{
                    throw new UserNotPermitException();
                }
                if(permissionNames.contains("edit")){
                    msg.setData(SiomConstants.LOGIN_ADMIN_PERMIT_MSG);
                    msg.setStatus(SiomConstants.LOGIN_SUCCESS);
                    msg.setMsg(SiomConstants.LOGIN_SUCCESS_MSG+SiomConstants.LOGIN_ADMIN_PERMIT_MSG);
               }else{
                    msg.setData(SiomConstants.LOGIN_ADMIN_NOT_PERMIT_MSG);
                    msg.setStatus(SiomConstants.LOGIN_FAILED);
                    msg.setMsg(SiomConstants.LOGIN_FAILED_MSG+SiomConstants.LOGIN_ADMIN_NOT_PERMIT_MSG);
                }
                return msg;
            } else {
                return msg;
            }
        } catch (IncorrectCredentialsException e) {
            msg.setStatus(SiomConstants.WRONG_PASSWORD);
            msg.setMsg(SiomConstants.WRONG_PASSWORD_MSG);
            return msg;
        } catch (ExcessiveAttemptsException e) {
            msg.setStatus(SiomConstants.FAILED_TOO_MUCH);
            msg.setMsg(SiomConstants.FAILED_TOO_MUCH_MSG);
            return msg;
        } catch (LockedAccountException e) {
            msg.setStatus(SiomConstants.USER_IS_LOCKED);
            msg.setMsg(SiomConstants.USER_IS_LOCKED_MSG);
            return msg;
        } catch (DisabledAccountException e) {
            msg.setStatus(SiomConstants.USER_IS_BANNED);
            msg.setMsg(SiomConstants.USER_IS_BANNED_MSG);
            return msg;
        } catch (ExpiredCredentialsException e) {
            msg.setStatus(SiomConstants.USER_IS_TIMEOUT);
            msg.setMsg(SiomConstants.USER_IS_TIMEOUT_MSG);
            return msg;
        } catch (UnknownAccountException e) {
            msg.setStatus(SiomConstants.USER_IS_NOT_EXIST);
            msg.setMsg(SiomConstants.USER_IS_NOT_EXIST_MSG);
            return msg;
        } catch (UnauthorizedException e) {
            msg.setStatus(SiomConstants.USER_IS_NOT_AUTH);
            msg.setMsg(SiomConstants.USER_IS_NOT_AUTH_MSG);
            return msg;
        } catch (UserWaittingPermitException e) {
            msg.setStatus(SiomConstants.LOGIN_WAITTING_PERMIT);
            msg.setMsg(SiomConstants.LOGIN_WAITTING_PERMIT_MSG);
            return msg;
        } catch (UserNotPermitException e) {
            msg.setStatus(SiomConstants.LOGIN_ADMIN_NOT_PERMIT);
            msg.setMsg(SiomConstants.LOGIN_ADMIN_NOT_PERMIT_MSG);
            return msg;
        } catch (AuthenticationException e) {
            msg.setStatus(SiomConstants.LOGIN_FAILED);
            msg.setMsg(SiomConstants.LOGIN_FAILED_MSG);
            return msg;
        }
    }

    /**
     * 登出
     */
    @RequestMapping(value = "/logout", method = RequestMethod.GET)
    @ResponseBody
    public ReturnMsg logout() {
        try {
            Subject currentUser = SecurityUtils.getSubject();
            currentUser.logout();
            ReturnMsg msg = new ReturnMsg();
            msg.setStatus(1);
            msg.setMsg("logout success");
            return msg;
        } catch (Exception e) {
            LOGGER.error("catch exception : ", e);
            ReturnMsg msg = new ReturnMsg();
            msg.setStatus(0);
            msg.setMsg("logout failed");
            return msg;
        }
    }


    /**
     * 获取登录状态
     *
     * @return ReturnMsg
     */
    @RequestMapping(value = "/isLogin", method = RequestMethod.GET)
    @ResponseBody
    public ReturnMsg isLogin() {
        ReturnMsg msg = new ReturnMsg();
        try {
            Subject subject = SecurityUtils.getSubject();
            if (subject.isAuthenticated()) {
                msg.setStatus(0);
                msg.setMsg("login success");
                msg.setData("{\"card\" : \"" + SessionUtil.getSessionValue("card") + "\", \"uid\" :　\"" + SessionUtil.getSessionValue("uid")
                        + "\", \"name\" : \"" + SessionUtil.getSessionValue("name") + "\", \"role\" : \"" + SessionUtil.getSessionValue("role") + "\", \"permission\" : \"" + SessionUtil.getSessionValue("permission") + "\"}");
            } else {
                msg.setStatus(1);
                msg.setMsg("user is not login");
            }
        } catch (Exception e) {
            LOGGER.error("AuthController.isLogin() catch exception : ", e);
            msg.setStatus(2);
            msg.setMsg("query user login status failed");
            return msg;
        }
        return msg;
    }



}
